package stream;


import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;


/**
 * @description: Stream中间操作
 * @author: apple
 * @date:  2022/1/4 6:13 下午
 * @version 1.0
 **/
public class StreamAPITest {

    // 一、筛选与切片
    @Test
    public void test1() {
        // 数据筛选操作，比较原始的写法
        final List<StreamTest.Employee> data = StreamTest.Employee.getData();
        data.stream().filter(new Predicate<StreamTest.Employee>() {
            @Override
            public boolean test(StreamTest.Employee employee) {
                return employee.getAge() > 26;
            }
        }).forEach(new Consumer<StreamTest.Employee>() {
            @Override
            public void accept(StreamTest.Employee employee) {
                System.out.println(employee);
            }
        });

    }

    // 筛选与切片filter
    @Test
    public void test2() {
        // 筛选int
        final Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6);
        integerStream.filter(i -> i % 2 == 0).forEach(System.out::println);
        // 筛选员工对象
        final List<StreamTest.Employee> data = StreamTest.Employee.getData();
        // 年龄大于26岁的
        data.stream().filter(e -> e.getAge() > 26).forEach(System.out::println);

        // 筛选字符串
        final Stream<String> stream = Arrays.stream(new String[]{"aaa","bb","cc"});
        // 名称大于两个字的
        stream.filter(e -> e.length() > 2).forEach(System.out::println);
    }

    // 筛选与切片limit(n) 截断流，不超过N个
    @Test
    public void test3() {
        final List<StreamTest.Employee> data = StreamTest.Employee.getData();
        final Stream<StreamTest.Employee> stream = data.stream();
        // 只查询前两个
        stream.limit(2).forEach(System.out::println);
    }

    // 筛选与切片skip(n) 跳过N个元素
    @Test
    public void test4() {
        final List<StreamTest.Employee> data = StreamTest.Employee.getData();
        final Stream<StreamTest.Employee> stream = data.stream();
        // 跳过前面3个元素，从第4个开始，不能写负数
        stream.skip(3).forEach(System.out::println);
    }


    // 筛选与切片distinct筛选重复的
    @Test
    public void test5() {
        final List<StreamTest.Employee> data = StreamTest.Employee.getData();
        final Stream<StreamTest.Employee> stream = data.stream();
        // 跳过前面3个元素，从第4个开始，不能写负数
        stream.distinct().forEach(System.out::println);
    }


    // 二、映射map
    @Test
    public void test6() {
        final List<String> list = Arrays.asList("aa", "bb", "cc");
        final Stream<String> stream = list.stream();
        // 转大写
        stream.map(str -> str.toUpperCase()).forEach(System.out::println);

        System.out.println("--");
        final Stream<String> stream1 = list.stream();
        // 首字符转大写
        stream1.map(str -> str.substring(0,1).toUpperCase()+str.substring(1) ).forEach(System.out::println);

        // 查询姓名3个字以上的员工姓名
        final List<StreamTest.Employee> data = StreamTest.Employee.getData();
        // 获取Employee类型的流
        final Stream<StreamTest.Employee> stream2 = data.stream();
        // 方法推断
        final Stream<String> stringStream = stream2.map(StreamTest.Employee::getName);

        stringStream.filter(e -> e.length() > 2).forEach(System.out::println);






    }

    // 三、排序sorted
    @Test
    public void test7() {

        final List<Integer> list = Arrays.asList(2, 4, 6, 7, 45, 2234, 123);
        final Stream<Integer> sorted = list.stream().sorted();
        sorted.forEach(System.out::println);
    }

    // 四、中断操作
    @Test
    public void test8() {
        final List<StreamTest.Employee> data = StreamTest.Employee.getData();
        final Stream<StreamTest.Employee> stream = data.stream();
        // 查询年龄大于18岁的
        final boolean b = stream.allMatch(e -> e.getAge() > 18);
        System.out.println(b);

        // 查询是否包含大于等于28岁的
        final boolean b1 = data.stream().anyMatch(e -> e.getAge() >=28);
        System.out.println(b1);

        // 查询是否没有匹配的元素
        // 查询是否没有性王的
        final boolean noneMatch = data.stream().noneMatch(e -> e.getName().startsWith("王"));
        System.out.println(noneMatch);


        // 查找第一个
        final Optional<StreamTest.Employee> first = data.stream().findFirst();
        System.out.println(first);

        // 查找任意一个
        final Optional<StreamTest.Employee> any = data.parallelStream().findAny();
        System.out.println(any);

    }

    // 四、中断操作
    @Test
    public void test9() {
        final List<StreamTest.Employee> data = StreamTest.Employee.getData();
        final Stream<StreamTest.Employee> stream = data.stream();
        // 查询条数
        final long count = stream.filter(e -> e.getAge() > 26).count();
        System.out.println(count);

        // 查找年龄最大的
        final Stream<Integer> integerStream = data.stream().map(StreamTest.Employee::getAge);
        final Optional<Integer> max = integerStream.max(Integer::compare);
        System.out.println(max);

        // 查找年龄最小的
        final Optional<Integer> min = data.stream().map(StreamTest.Employee::getAge).min(Integer::compare);
        System.out.println(min);
    }


    // 五、归约操作
    @Test
    public void test10() {

        final List<Integer> list = Arrays.asList(1, 2, 3);
        final Stream<Integer> stream = list.stream();
        // 求合
        final Integer reduce = stream.reduce(0, Integer::sum);
        System.out.println(reduce);
    }

    @Test
    public void test11() {

        // 低于80%， 79.31%
        System.out.println("--》" + (79.31 / 80.00 * 60 ));
        System.out.println("--》" + (60.00 * 79.31 / 80.00));

        // 高于80% ， 88.24%
        System.out.println("-->" + ((88.24 - 80.00) / 20.00 * 40.00 + 60.00));

        // 高于80% ， 83.33%
        System.out.println("-->" + ((83.33 - 80.00) / 20.00 * 40.00 + 60.00));

        Function<Integer,String> fun = new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) {
                return "Represents a function that accepts one argument and produces a result.";
            }
        };
        Function<Integer,String> fun2 = (i) -> i+"abc";
        final String apply = fun2.apply(20);
        System.out.println(apply);



        Predicate<String> p = new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return false;
            }
        };
    }
}
